/*
 * device_id.c
 *
 *  Created on: 2023年7月28日
 *      Author: fjx
 */
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include "device.h"
#include "device_rfmid.h"
#include "app_log.h"
#include "util.h"

//节点注册信息,每一位代表一个节点信息

/*  rfmID[x]
*  小端模式，rfmID[0]
*            bit0=ID1, bit1=ID2, bit2=ID3, bit3=ID4,
*            bit4=ID5, bit5=ID6, bit6=ID7, bit7=ID8
*            rfmID[1]
*            bit0=ID9, bit1=ID10, bit2=ID11, bit3=ID12,
*            .....
*            
*/


uint8_t RfmID[NODE_JOIN_INFO_LENGTH]={0};

void clearNodeJoinCount(void)
{
  uint8_t buf[NODE_JOIN_INFO_LENGTH];
  memset(buf,0,sizeof(buf));
  setThisParam(ENbyNodeJoinInfo,buf);

}
/*
 *  获取当前RFM注册的总数量
 */
uint16_t getNodeJoinCount(void)
{
  uint8_t buf[NODE_JOIN_INFO_LENGTH];
  uint8_t i=0,j=0;
  uint16_t count = 0;
  #if defined (CONFIG_DEBUG_DEVICE_RFMID)
  memcpy(buf,RfmID,NODE_JOIN_INFO_LENGTH);
  #else
  getThisParam(ENbyNodeJoinInfo,buf);
  #endif

  for(i=0;i<NODE_JOIN_INFO_LENGTH;i++){
      for(j=0;j<8;j++){
          if(j==0){
            if( (buf[i]&0x01) == 0x01 ){
              count +=1;
            }
          }
          else{
            if(((buf[i]>>j)&0x01) == 1){
              count +=1;
            }
          }
      }
  }

  return count;
}
/*
 * 判断RFMId是否已存在
 *  @return  返回0，该RFMID存在； 返回1，该RFMID不存在
 */
bool isRfmId(uint16_t id)
{
  uint8_t i,j,k;
  uint8_t buf[NODE_JOIN_INFO_LENGTH];

  memset(buf,0,sizeof(buf));
  i=id/8;
  j=id%8;
  if(j==0){
    buf[i-1] = 0x80;
    k = i-1;
  }
  else {
    buf[i] = 1<<(j-1);
    k = i;
  }

  i = k;
  getThisParam(ENbyNodeJoinInfo,RfmID);
  if( buf[i]==(RfmID[i]&buf[i]) && buf[i]!=0 ){
    //printf("id=%d,same,buf[i]=%d\n",id,buf[i]);
    return 0;
  }
  //printf("id=%d,diff\n",id);

  return 1;
}

uint8_t setRfmIdToPacket(uint16_t id)
{
  uint8_t buf[NODE_JOIN_INFO_LENGTH],origin[NODE_JOIN_INFO_LENGTH];
  uint8_t i,j;
  i=id/8;
  j=id%8;
  memset(buf,0,sizeof(buf));

  if(j==0){
    buf[i-1] =0x80;
  }
  else {
    buf[i] = 1<<(j-1);

  }



//打印数据
#if defined (CONFIG_DEBUG_DEVICE_RFMID)
  orDataLine(RfmID,buf,NODE_JOIN_INFO_LENGTH);
  if(id < 10 || id > 250){
    printf("\n\ni=%d, j=%d\n",i,j);
    printf("id = %d \n",id);

    DS_app_log_hexdump("rfm id:",buf,sizeof(buf));
  }
  DS_app_log_hexdump("rfm id:",RfmID,sizeof(buf));
#else
  getThisParam(ENbyNodeJoinInfo,origin);
  orDataLine(origin,buf,NODE_JOIN_INFO_LENGTH);
  //write
  setThisParam(ENbyNodeJoinInfo,origin);
#endif
  return 0;
}

/*
 *@note 通过指定rfmid范围查询mac是否存在
 *@return 0, 不存在; 返回非0,存在，返回ID
 */
uint8_t isRfmMac(uint8_t st_id,uint8_t lt_id,uint8_t *mac)
{
  uint8_t i=0;
  uint8_t mac_buf[MAC_ADDRESS_LENGTH]={0};

  for(i=st_id; i<lt_id; i++){
      //1.id=i，是否存在；存在进行mac比较
      if(isRfmId(i) == 0){
          #if defined (CONFIG_DEBUG_DEVICE_RFMID)
          //mac 地址
          #else
          getNodeJoinMac(mac_buf,i);
          #endif

          if(memcmp(mac_buf,mac,MAC_ADDRESS_LENGTH) == 0){
              //MAC地址相同
              //12345678
              return i;
          }
      }
  }
  return 0;
}


/*
 *@note 通过deviceType查找设备是否可以注册，如果可以注册,返回0和ID
 *@note TODO: HUB写入RfmID、节点codeAB时间在收到节点确认后写入
 *@retrun =0，为空；=-1，已存在相同的mac; =-2,该类型设备已注册满。=-3,设备已全部注册满
 *@retrun
 */
uint8_t isRfmIdEmpty(uint8_t deviceType,uint8_t *mac,uint8_t *id)
{
  if(deviceType >= EN_DEVICE_TYPE_IO_FIRST
      && deviceType <= EN_DEVICE_TYPE_IO_LAST){
      //IO type
      //rfmID [RFMID_EN_INDEX_IO_FIRST,RFMID_EN_INDEX_IO_LAST]
      //1. 判断ID是否存在，
      //2. 判断mac地址是否相同
      *id = isRfmMac(RFMID_EN_INDEX_IO_FIRST,RFMID_EN_INDEX_IO_LAST,mac);
      if(*id == 0){
          return 0;//不存在
      }else{
          return 1;
      }
  }else if(deviceType >= EN_DEVICE_TYPE_SOUNDER_FIRST
      && deviceType <= EN_DEVICE_TYPE_SOUNDER_LAST){
      //SOUND type
      //rfmID [RFMID_EN_INDEX_SOUNDER_FIRST,RFMID_EN_INDEX_SOUNDER_LAST]
      *id = isRfmMac(RFMID_EN_INDEX_SOUNDER_FIRST,RFMID_EN_INDEX_SOUNDER_LAST,mac);
      if(*id == 0){
          return 0;//不存在
      }else{
          return 1;
      }
  }else if(deviceType >= EN_DEVICE_TYPE_KEYPAD_FIRST
      && deviceType <= EN_DEVICE_TYPE_KEYPAD_LAST){
      //KEYPAD type
      //rfmID [RFMID_EN_INDEX_KEYPAD_FIRST,RFMID_EN_INDEX_KEYPAD_LAST]
      *id = isRfmMac(RFMID_EN_INDEX_KEYPAD_FIRST,RFMID_EN_INDEX_KEYPAD_LAST,mac);
      if(*id == 0){
          return 0;//不存在
      }else{
          return 1;
      }
  }else if(deviceType >= EN_DEVICE_TYPE_FOB_FIRST
      && deviceType <= EN_DEVICE_TYPE_FOB_LAST){
       //FOB type
      //rfmID [RFMID_EN_INDEX_FOB_FIRST,RFMID_EN_INDEX_FOB_LAST]
      *id = isRfmMac(RFMID_EN_INDEX_FOB_FIRST,RFMID_EN_INDEX_FOB_LAST,mac);
      if(*id == 0){
          return 0;//不存在
      }else{
          return 1;
      }
  }else{
      DS_app_log_error("device type not supported!\n");
  }
  return 2; //参数错误。
}
/*

return =0,有空的
*/
bool findEmptyType (uint8_t st_id,uint8_t lt_id,uint8_t *id)
{

  uint8_t i=0;
 

  for(i=st_id; i<=lt_id; i++){
      //id=i，是否存在；存在进行mac比较
      if(isRfmId(i)!= 0){
        *id=i;
        DS_app_log_info("[%d~%d] find %d empty\n",st_id,lt_id,*id);
        return 0;
      }
  }
  return 1;
}


bool findEmptyRfmId(uint8_t deviceType,uint8_t *id)
{
  uint8_t _id =0;
  if(deviceType >= EN_DEVICE_TYPE_IO_FIRST
      && deviceType <= EN_DEVICE_TYPE_IO_LAST){
      //IO type
      //rfmID [RFMID_EN_INDEX_IO_FIRST,RFMID_EN_INDEX_IO_LAST]
      //1. 判断ID是否存在，
      //2. 判断mac地址是否相同
      if(findEmptyType(RFMID_EN_INDEX_IO_FIRST,RFMID_EN_INDEX_IO_LAST,&_id) == 0){
          //空的ID
          *id = _id;
          return 0;
      }else{
          return 1;
      }
  }else if(deviceType >= EN_DEVICE_TYPE_SOUNDER_FIRST
      && deviceType <= EN_DEVICE_TYPE_SOUNDER_LAST){
      //SOUND type
      //rfmID [RFMID_EN_INDEX_SOUNDER_FIRST,RFMID_EN_INDEX_SOUNDER_LAST]
      if(findEmptyType(RFMID_EN_INDEX_SOUNDER_FIRST,RFMID_EN_INDEX_SOUNDER_LAST,&_id) == 0){
          //空的ID
          *id = _id;
          return 0;
      }else {
          return 1;
      }
  }else if(deviceType >= EN_DEVICE_TYPE_KEYPAD_FIRST
      && deviceType <= EN_DEVICE_TYPE_KEYPAD_LAST){
      //KEYPAD type
      //rfmID [RFMID_EN_INDEX_KEYPAD_FIRST,RFMID_EN_INDEX_KEYPAD_LAST]
      if(findEmptyType(RFMID_EN_INDEX_KEYPAD_FIRST,RFMID_EN_INDEX_KEYPAD_LAST,&_id) == 0){
          //空的ID
          *id = _id;
          return 0;
      }else{
          return 1;
      }
  }else if(deviceType >= EN_DEVICE_TYPE_FOB_FIRST
      && deviceType <= EN_DEVICE_TYPE_FOB_LAST){
      //FOB type
      //rfmID [RFMID_EN_INDEX_FOB_FIRST,RFMID_EN_INDEX_FOB_LAST]
      if(findEmptyType(RFMID_EN_INDEX_FOB_FIRST,RFMID_EN_INDEX_FOB_LAST,&_id) == 0){
          //空的ID
          *id = _id;
          return 0;
      }else{
          return 1;
      }
  }else {
      DS_app_log_error("device type not supported!\n");
  }
  return 1;
}

/*
 *@note 通过id,进行存储
 *
 */
//0 分配了ID， 1 ID已存在， 2 分配已满 3出错
uint8_t setRfmId(uint8_t deviceType,uint8_t *mac,uint8_t *id)
{
  uint8_t _rfmid=0;
  uint8_t iret = 0;
  iret = isRfmIdEmpty(deviceType,mac,id);   //0 不存在； 1 存在； 2出错

  if(iret ==  0){ //不存在
     //不存在,写入;
     //1、查找空的区域，
     //2.写入_rfmid
     if( findEmptyRfmId(deviceType,&_rfmid) == 0){ //找到了未分配的区域
         DS_app_log_info("_rfmid = %d\n",_rfmid);
         *id = _rfmid;
         setRfmIdToPacket(_rfmid);
        #if defined (CONFIG_DEBUG_DEVICE_RFMID)
        #else 
        setNodeJoinMac(mac,_rfmid);
        #endif
        return 0;
     }else{ //都被分配完了
        DS_app_log_error("Device join device type memory full!\n");
        return 2;
     }
 }else if(iret == 1){
     //存在
     return 1;
 }else{
     //出错
     return 3;
 }
}
